import random
import time
from datetime import datetime
import paramiko
import schedule
from openpyxl.workbook import Workbook

from logger.logger import Log
import api.config


# 用于测试Flash存储器的读写 -- ssh连接
# @AUTHOR -- 陈选 -- 2024-04-18
class flashConnect:
    def start(self):
        try:
            # SSH连接
            self.sshLogin()
            # 计算测试结束时间
            reboot_time = api.config.Config.arg['TestCase']['RebootTime']
            end_time = time.time() + reboot_time

            # 循环执行定时任务，直到测试结束时间
            while time.time() < end_time:
                # 执行重启操作并重新建立SSH连接
                self.perform_file_io_and_record_data()
                schedule.run_pending()
                # 等待10分钟
                # time.sleep(600)
                time.sleep(30)

            # 运行结束后输出 Excel 表格
            self.write_to_excel()
        except Exception as e:
            Log.logger.info(f"发现异常: {e}")
            Log.logger.error(f"发现异常: {e}")

    def perform_file_io_and_record_data(self):
        # 获取当前时间
        time_now = get_time()

        try:
            # 执行重启操作并重新建立SSH连接
            self.sendFlash()
            time.sleep(20)
            self.sshLogin()
            # 记录重启时间和结果到列表中
            self.recorded_data.append([time_now, "Success", ""])
            self.FlashPassTime += 1
        except Exception as e:
            # 如果重启操作或SSH连接失败，记录错误信息
            self.FlashFailedTime += 1
            self.recorded_data.append([time_now, "Failed", str(e)])
            Log.logger.info(f"重启操作或SSH连接失败发现异常: {e}")
            Log.logger.error(f"重启操作或SSH连接失败发现异常: {e}")
            # 在捕获到异常后继续执行循环中的下一步操作
            return

    def sendFlash(self):
        try:
            self.invoke.send("reboot".encode())
            time.sleep(2)
            outputOfEcho = self.invoke.recv(5000).decode('utf-8')
            Log.logger.info(outputOfEcho)
        except Exception as e:
            Log.logger.info(f"发送reboot指令发现异常: {e}")
            Log.logger.error(f"发送reboot指令发现异常: {e}")

    def write_to_excel(self):
        try:
            # 创建一个新的工作簿
            wb = Workbook()
            # 选择活动工作表
            ws = wb.active
            # 设置第一列和第二列的宽度
            ws.column_dimensions['A'].width = 20  # 设置第一列宽度为20
            ws.column_dimensions['B'].width = 20  # 设置第二列宽度为20
            ws.column_dimensions['A'].height = 20  # 设置第一列宽度为20
            ws.column_dimensions['B'].height = 20  # 设置第二列宽度为20
            # 写入数据
            ws.append(['Reboot指令发送时间', '测试结果'])
            for data_row in self.recorded_data:
                ws.append(data_row)
            # 保存工作簿
            pass_rate = (self.FlashPassTime / (self.FlashPassTime + self.FlashFailedTime)) * 100
            ws.append(['测试总次数', self.FlashPassTime + self.FlashFailedTime])
            ws.append(['测试通过次数', self.FlashPassTime])
            ws.append(['测试失败次数', self.FlashFailedTime])
            ws.append(['测试通过率:', '{:.2f}%'.format(pass_rate)])  # 保留两位小数
            current_time = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
            wb.save(f'report/{current_time}_Reboot.xlsx')
        except Exception as e:
            Log.logger.info(f"写入 Excel 表格时发生异常: {e}")
            Log.logger.error(f"写入 Excel 表格时发生异常: {e}")

    def close(self):
        if self.is_ssh_con:
            self.ssh.close()
        else:
            self.serial.close()

    def sshLogin(self):
        self.ssh.load_system_host_keys()
        self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        self.ssh.connect(self.connect_ip, port=self.connect_port, username=self.connect_user,
                         password=self.connect_pwd)
        self.is_connect = True
        self.invoke = self.ssh.invoke_shell()
        time.sleep(10)
        outputOfEcho = self.invoke.recv(5000).decode('utf-8')
        Log.logger.info(outputOfEcho)

    def __init__(self):
        self.is_connect = False
        self.pid = None
        self.pid_kill = True
        self.data = str()
        self.serial = None
        self.invoke = None
        self.end_str = api.config.Config.arg['TestCase']['endstr']
        self.exepath = api.config.Config.arg['TestCase']['exepath']
        self.exe = api.config.Config.arg['TestCase']['exe']
        self.FlashStatus = {}
        self.FlashPassTime = 0
        self.FlashFailedTime = 0
        self.recorded_data = []
        self.is_ssh_con = True if api.config.Config.arg['Gateway']['Connect'] == 'SSH' else False
        if self.is_ssh_con:
            self.ssh = paramiko.SSHClient()
            self.connect_ip = api.config.Config.arg['Gateway']['IPAddress']
            self.connect_user = api.config.Config.arg['Gateway']['Username']
            self.connect_pwd = api.config.Config.arg['Gateway']['Password']
            self.connect_port = api.config.Config.arg['Gateway']['Port']
        else:
            self.login_by_serial = False
            self.read_serial_data = False
            # 串行端口的名称或者设备文件名
            self.serial_port = api.config.Config.arg['Gateway']['SerialPort']
            # 波特率
            self.serial_bitrate = int(api.config.Config.arg['Gateway']['SerialBitrate'])


def get_time() -> str:
    return time.strftime("%Y%m%d_%H_%M_%S", time.localtime())
